require 'rexml/document'
require 'rexml/streamlistener'
require 'infolr_log'
include REXML

# if performance is not so good, use sax instead 
# http://textsnippets.com/posts/show/870
module Infolr
  class FeedEntry
    attr_accessor :title
    attr_accessor :link
    attr_accessor :summary
    attr_accessor :content
    attr_accessor :item_id
    attr_accessor :feed_url
  end
  class ReadingListParser
    # parse a reading list xml file genereated by google reader 
    # http://www.google.com/reader/atom/user/02303053382307507029/state/com.google/reading-list
    # return a list of entries of feed items
    def ReadingListParser.parse(file)
      $logger.debug "before document new"
      doc = REXML::Document.new(file, { :compress_whitespace => %w{ :raw } })
      $logger.debug "after document new"
      entries = []
      doc.elements.each('feed/entry') do |entry|
        $logger.debug "a new entry will be processed."
        feed_entry = FeedEntry.new
        begin
          feed_entry.title = entry.elements['title'].text
          if(entry.elements['summary']==nil)
            feed_entry.summary = ''  
          else
            feed_entry.summary = entry.elements['summary'].text
          end
          if(entry.elements['content']==nil)
            feed_entry.content = ''  
          else
            feed_entry.content = entry.elements['content'].text
          end
          
          feed_entry.link = entry.elements["link[@rel='alternate']"].attributes['href']
          feed_entry.item_id = entry.elements['id'].text
          feed_entry.feed_url = entry.elements['source'].attributes['gr:stream-id']
          entries << feed_entry
        rescue Exception
          $logger.warn "an exception occur when parsing reading list: #{feed_entry.title}"
        end
      end
      return entries
    end
    class FeedEntryBuilderListener
      include StreamListener
      attr_accessor :entries
      @context = :feed
      def tag_start(name,attributes)
        if(name == 'entry')
          @context = :entry
          @feed_entry = FeedEntry.new
          $logger.debug 'new entry has been created.'
        elsif(name == 'source')
          @context = :source
          @feed_entry.feed_url = attributes['gr:stream-id']
        elsif(name == 'link' and @context == :entry and attributes['rel'] == 'alternate')
          @feed_entry.link = attributes['href']
        end
      end
      def text(text)
        @text = text
      end
      def tag_end(name)
        if(name == 'entry')
          @entries << @feed_entry
        elsif(name == 'title' and @context == :entry)
          @feed_entry.title = @text       
        elsif(name == 'id' and @context == :entry)
          @feed_entry.item_id = @text
        elsif(name == 'content' and @context == :entry)
          @feed_entry.content = @text
        elsif(name == 'summary' and @context == :entry)
          @feed_entry.summary = @text
        end
      end
    end
    def ReadingListParser.stream_parse(file)
      listener = FeedEntryBuilderListener.new
      listener.entries = []
      $logger.debug "before stream parser new"
      parser = Parsers::StreamParser.new(file, listener)
      $logger.debug "after stream parser new"
      parser.parse
      return listener.entries
    end
  end
end
